// src/utils/AudioCache.ts
interface CachedAudio {
    musicKey: string;
    url: string;
    cachedAt: number;
}

export class AudioCache {
    private dbName: string;
    private storeName: string;
    private db: IDBDatabase | null = null;

    constructor(dbName: string = 'AudioCacheDB', storeName: string = 'audio') {
        this.dbName = dbName;
        this.storeName = storeName;
    }

    // 初始化数据库
    public async initDB(): Promise<IDBDatabase> {
        return new Promise((resolve, reject) => {
            const request = indexedDB.open(this.dbName, 1);

            request.onupgradeneeded = (event: IDBVersionChangeEvent) => {
                const db = (event.target as IDBOpenDBRequest).result;
                if (!db.objectStoreNames.contains(this.storeName)) {
                    db.createObjectStore(this.storeName, { keyPath: 'musicKey', autoIncrement: true });
                }
            };

            request.onsuccess = (event: Event) => {
                this.db = (event.target as IDBOpenDBRequest).result;
                resolve(this.db);
            };

            request.onerror = (event: Event) => {
                reject(`IndexedDB打开失败: ${(event.target as IDBOpenDBRequest).error}`);
            };
        });
    }

    // 缓存音频文件的访问链接
    public async cacheAudioUrl(musicKey: string, url: string): Promise<boolean> {
        if (!this.db) await this.initDB();

        try {
            // 检查是否已缓存
            const exists = await this.getAudioUrl(musicKey);
            if (exists) return true;

            // 存储到IndexedDB
            await new Promise<void>((resolve, reject) => {
                const tx = this.db!.transaction(this.storeName, 'readwrite');
                const store = tx.objectStore(this.storeName);

                store.put({
                    musicKey,
                    url,
                    cachedAt: Date.now()
                });

                tx.oncomplete = () => resolve();
                tx.onerror = () => reject(tx.error);
            });

            return true;
        } catch (error) {
            console.error('缓存音频链接失败:', error);
            return false;
        }
    }

    // 获取缓存的音频链接
    public async getAudioUrl(musicKey: string): Promise<CachedAudio | null> {
        if (!this.db) await this.initDB();

        try {
            const tx = this.db!.transaction(this.storeName, 'readonly');
            const store = tx.objectStore(this.storeName);

            return new Promise((resolve, reject) => {
                const request = store.openCursor();
                request.onsuccess = () => {
                    const cursor = request.result;
                    if (cursor) {
                        const value = cursor.value;
                        if (value.musicKey === musicKey) {
                            resolve(value);
                        } else {
                            cursor.continue();
                        }
                    } else {
                        resolve(null);
                    }
                };
                request.onerror = () => reject(request.error);
            });
        } catch (error) {
            console.error('获取音频链接失败:', error);
            return null;
        }
    }

    // 删除缓存
    public async deleteAudioUrl(musicKey: string): Promise<void> {
        if (!this.db) await this.initDB();

        return new Promise((resolve, reject) => {
            const tx = this.db!.transaction(this.storeName, 'readwrite');
            const store = tx.objectStore(this.storeName);
            const request = store.delete(musicKey);

            request.onsuccess = () => resolve();
            request.onerror = () => reject(request.error);
        });
    }

    // 获取所有缓存
    public async getAllCache(): Promise<CachedAudio[]> {
        if (!this.db) await this.initDB();

        return new Promise((resolve, reject) => {
            const tx = this.db!.transaction(this.storeName, 'readonly');
            const store = tx.objectStore(this.storeName);
            const request = store.getAll();

            request.onsuccess = () => resolve(request.result || []);
            request.onerror = () => reject(request.error);
        });
    }

    // 清空所有缓存
    public async clearAllCache(): Promise<void> {
        if (!this.db) await this.initDB();

        return new Promise((resolve, reject) => {
            const tx = this.db!.transaction(this.storeName, 'readwrite');
            const store = tx.objectStore(this.storeName);
            const request = store.clear();

            request.onsuccess = () => resolve();
            request.onerror = () => reject(request.error);
        });
    }
}